﻿using System;
using VS4CRM.Lib;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Rhino.Mocks;
using System.IO;

namespace VS4CRM.Test
{
    #region Context
    internal class Context
    {
        public string CrmServiceReturnValue { get; set; }
        public string FileName { get; set; }
        public string ParentFolder { get; set; }
        public string ExpectedRequestXml { get; set; }
        public string ExpectedResult { get; set; }
    }
    #endregion

    /// <summary>
    ///This is a test class for ScriptUploaderTest and is intended
    ///to contain all ScriptUploaderTest Unit Tests
    ///</summary>
    [TestClass()]
    public class ScriptUploaderTest
    {
        #region ExportFromCRMTest
        /// <summary>
        /// Helper method that serve ExportFromCRM test methods
        /// </summary>
        /// <param name="context">Test Context with parameters to test</param>
        private void ExportFromCRMTest(Context context)
        {
            MockRepository mocks = new MockRepository();
            var service = mocks.Stub<ICrmService>();

            string expectedRequestXml = context.ExpectedRequestXml;
            using (mocks.Record())
            {
                service.Expect(serv => serv.Execute(Arg<ExportXmlRequest>.Matches(req => req.ParameterXml == expectedRequestXml)))
                    .Return(new ExportXmlResponse() { ExportXml = context.CrmServiceReturnValue });
            }

            mocks.ReplayAll();

            // Create the Uploader
            ScriptUploader uploader = new ScriptUploader(service);

            // Create an empty xml file in temporary directory
            string tempPath = String.Concat(Path.GetTempPath(), context.ParentFolder);
            string filePath = String.Concat(tempPath, Path.DirectorySeparatorChar, context.FileName);
            Directory.CreateDirectory(tempPath);

            File.WriteAllText(filePath, String.Empty);

            Assert.IsTrue(uploader.ExportFromCRM(filePath));

            // Verify content of the file
            string result = File.ReadAllText(filePath);
            Assert.AreEqual<String>(context.ExpectedResult, result);
        }
        #endregion

        #region ExportFromCRMFileTypeTest
        /// <summary>
        /// ExportFromCrm to file with not "xml" extension
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMFileTypeTest()
        {
            MockRepository mocks = new MockRepository();
            var service = mocks.Stub<ICrmService>();

            // Create the Uploader
            ScriptUploader uploader = new ScriptUploader(service);

            Assert.IsFalse(uploader.ExportFromCRM("doesnotmatter.other"));
        }
        #endregion

        #region ExportFromCRMEntityTest
        /// <summary>
        /// ExportFromCRM to file where some entities already saved
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMEntityTest()
        {
            var context = new Context()
            {
                ExpectedRequestXml = "<importexportxml><entities><entity>ca_testentity</entity></entities></importexportxml>",
                CrmServiceReturnValue = Resources.testentity,
                ExpectedResult = Resources.testentity,
                FileName = "ca_testentity.xml",
                ParentFolder = Lib.Context.EntitiesDirectoty
            };
            ExportFromCRMTest(context);
        }
        #endregion

        #region ExportFromCRMIsvConfigTest
        /// <summary>
        /// Export IsvConfig from crm test
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMIsvConfigTest()
        {
            var context = new Context()
            {
                ExpectedRequestXml = "<importexportxml><nodes><node>isvconfig</node></nodes></importexportxml>",
                CrmServiceReturnValue = Resources.ISV_Config,
                ExpectedResult = Resources.ISV_Config,
                FileName = "ISVConfig.xml",
                ParentFolder = Lib.Context.ExtensionsDirectory
            };
            ExportFromCRMTest(context);
        }
        #endregion

        #region ExportFromCRMSiteMapTest
        /// <summary>
        /// Export SiteMap from crm test
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMSiteMapTest()
        {
            var context = new Context()
            {
                ExpectedRequestXml = "<importexportxml><nodes><node>sitemap</node></nodes></importexportxml>",
                CrmServiceReturnValue = Resources.Sitemap,
                ExpectedResult = Resources.Sitemap,
                FileName = "Sitemap.xml",
                ParentFolder = Lib.Context.ExtensionsDirectory
            };
            ExportFromCRMTest(context);
        }
        #endregion

        #region ExportFromCRMWorkflowTest
        /// <summary>
        /// Export workflow from crm test
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMWorkflowTest()
        {
            var context = new Context()
            {
                ExpectedRequestXml = "<importexportxml><workflows><workflow>apply restricted partner security setting</workflow></workflows></importexportxml>",
                CrmServiceReturnValue = Resources.Apply_Restricted_Partner_Security_Setting,
                ExpectedResult = Resources.Apply_Restricted_Partner_Security_Setting,
                FileName = "Apply Restricted Partner Security Setting.xml",
                ParentFolder = Lib.Context.WorkflowsDirectory
            };
            ExportFromCRMTest(context); ;
        }
        #endregion

        #region ExportFromCRMRoleTest
        /// <summary>
        /// Export Security Role from crm test
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMRoleTest()
        {
            var context = new Context()
            {
                ExpectedRequestXml = "<importexportxml><securityroles><securityrole>headoffinance</securityrole></securityroles></importexportxml>",
                CrmServiceReturnValue = Resources.HeadOfFinance,
                ExpectedResult = Resources.HeadOfFinance,
                FileName = "HeadOfFinance.xml",
                ParentFolder = Lib.Context.SecurityRolesDirectory
            };
            ExportFromCRMTest(context);
        }
        #endregion

        #region ExportFromCRMTemplateTest
        /// <summary>
        /// Export Templates from crm test
        /// </summary>
        [TestMethod()]
        public void ExportFromCRMTemplateTest()
        {
            Assert.IsTrue(false);
        }
        #endregion

        #region ExportFromCRMOtherDirectoryFailTest
        [TestMethod()]
        [ExpectedException(typeof(VS4CRM.Lib.Exceptions.NotSupportedDirectoryName))]
        public void ExportFromCRMOtherDirectoryFailTest()
        {
            var context = new Context()
            {
                ExpectedRequestXml = "<importexportxml><nodes><node>isvconfig</node></nodes></importexportxml>",
                CrmServiceReturnValue = Resources.ISV_Config,
                ExpectedResult = Resources.ISV_Config,
                FileName = "ISVConfig.xml",
                ParentFolder = "Other Directory"
            };
            ExportFromCRMTest(context);
        }
        #endregion
    }
}
